/**
 * 深拷贝
 * 柒吟秦
 * 2022-02-07
*/
import dataType from "./dataType";

export default function deepClone (target) {
    const mapObj = new Map(); // 处理循环引用
    const clone = (target) => {
        // 基本数据类型直接返回
        let types = [ 'String', 'Number', 'BigInt', 'Boolean', 'Undefined', 'Null' ];
        if(types.includes(dataType(target).type)) return target;
        // 函数
        if(dataType(target).isFunction) {
            return new Function('return ' + target.toString()).call(this);
        }
        // symbol
        if(dataType(target).isSymbol) {
            return Object(Symbol.prototype.valueOf.call(target));
        }
        // 时间
        if(dataType(target).isDate) {
            return new Date(target.valueOf());
        }
        // 正则
        if(dataType(target).isRegExp) {
            const reFlags = /\w*$/;
            const result = new target.constructor(target.source, reFlags.exec(target));
            result.lastIndex = target.lastIndex;
            return result;
        }
        // 引用数据类型特殊处理
        const newObj = new target.constructor();
        // 判断处理循环引用
        if (mapObj.has(target)) {
            return mapObj.get(target);
        }
        // 不存在则第一次设置
        mapObj.set(target, newObj);
        // Map
        if(dataType(target).isMap) {
            target.forEach((v,k) => {
                newObj.set(k, clone(v));
            });
            return newObj;
        }
        // Set
        if(dataType(target).isSet) {
            for(let val of target.values()) {
                newObj.add(clone(val));
            }
            return newObj;
        }
        // 对象 或 数组
        if(dataType(target).isObject || dataType(target).isArray ){
            for(let key in target) {
                newObj[key] = clone(target[key]);
            }
            return newObj;
        }
        // 其它类型直接返回
        return target;
    };
    return clone(target);
};
